package com.zgw.his.design.resource.ui;

import java.util.HashMap;
import java.util.Map;

import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.TreeEditor;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.MenuAdapter;
import org.eclipse.swt.events.MenuEvent;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeItem;
import org.eclipse.ui.part.ViewPart;

import com.zgw.his.design.common.RcpResourceManager;
import com.zgw.his.design.model.Folder;
import com.zgw.his.design.model.Template;

public abstract class ResourceTreeUI extends ViewPart {

	public static final String ID = "com.zgw.his.design.resource.ResourceTreeUI"; //$NON-NLS-1$
	private static String defaultContent;
	protected Tree tree;
	private TreeEditor ed;
	public Map<Object, TreeItem> treeItems = new HashMap<Object, TreeItem>();
	// =============================
	// Image
	// =============================
	private static final Image imageFolder = RcpResourceManager.getPluginImage(
			"com.zgw.his.emr.design", "icons/folder.gif");
	private static final Image imageFile = RcpResourceManager.getPluginImage(
			"com.zgw.his.emr.design", "icons/file.gif");
	protected static final Image image_state_update = RcpResourceManager.getPluginImage(
			"com.zgw.his.emr.design", "icons/edited_ov.gif");
	protected static final Image image_state_new = RcpResourceManager.getPluginImage(
			"com.zgw.his.emr.design", "icons/question_ov.gif");
	Action actPreview, actSubmit, actNew, actNewFolder, actDel;

	public ResourceTreeUI() {
	}

	/**
	 * Create contents of the view part.
	 * 
	 * @param parent
	 */
	@Override
	public void createPartControl(Composite parent) {
		Composite container = new Composite(parent, SWT.NONE);
		container.setLayout(new FillLayout(SWT.HORIZONTAL));
		{
			tree = new Tree(container, SWT.BORDER);
			ed = new TreeEditor(tree);
			ed.horizontalAlignment = SWT.RIGHT;
			ed.grabHorizontal = true;
			tree.addSelectionListener(new SelectionAdapter() {
				@Override
				public void widgetDefaultSelected(SelectionEvent e) {
					doOpenResource();
				}
			});
			buildTree();
		}

		createActions();
		initializeToolBar();
		initializeMenu();
		initializeListener();
	}

	protected void initializeListener() {
		tree.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseUp(MouseEvent e) {
				if (tree.getItem(new Point(e.x, e.y)) == null) {
					tree.setSelection(new TreeItem[] {});
				}
			}
		});
		tree.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetDefaultSelected(SelectionEvent e) {
				if (e.detail <= 0 && e.item != null
						&& e.item instanceof TreeItem) {
					TreeItem item = (TreeItem) e.item;
					item.setExpanded(!item.getExpanded());
				}
			}
		});
		tree.addPaintListener(new PaintListener() {
			public void paintControl(PaintEvent e) {
				for (TreeItem i : tree.getItems()) {
					redrawItem(e.gc, i);
				}
			}
		});
	}

	protected void doRefresh() {

	}

	protected Object getSelectedData() {
		if (tree.getSelection().length > 0) {
			return tree.getSelection()[0].getData();
		}
		return null;
	}

	protected void doCreateFolder() {
		Object selectData = getSelectedData();
		TreeItem pi = null;
		if (selectData instanceof Folder) {
			pi = tree.getSelection()[0];
		} else if (selectData instanceof Template) {
			pi = tree.getSelection()[0].getParentItem();
		}
		final TreeItem parent = pi;
		final TreeItem item = pi == null ? new TreeItem(tree, SWT.NONE)
				: new TreeItem(pi, SWT.NONE);

		final Text editor = new Text(tree, SWT.BORDER);
		tree.setSelection(item);
		editor.setText("新目录");
		editor.setFocus();
		editor.addKeyListener(new KeyAdapter() {
			@Override
			public void keyPressed(KeyEvent e) {
				if (e.character == SWT.CR) {
					try {
						Folder f = newFolder(parent, editor.getText());
						if (f != null) {
							tree.setSelection(createFolderItem(f, parent));
							editor.dispose();
							item.dispose();
						} else {
							editor.setSelection(0);
						}
					} catch (Exception e1) {
						e1.printStackTrace();
					}
				} else if (e.character == SWT.ESC) {
					editor.dispose();
					item.dispose();
				}
			}
		});
		ed.setEditor(editor, item);
		editor.setSelection(0, editor.getText().length());
	}

	protected void doCreateTemplate() {
		Object selectData = getSelectedData();
		TreeItem pi = null;
		if (selectData instanceof Folder) {
			pi = tree.getSelection()[0];
		} else if (selectData instanceof Template) {
			pi = tree.getSelection()[0].getParentItem();
		}
		final TreeItem parent = pi;
		final TreeItem item = pi == null ? new TreeItem(tree, SWT.NONE)
				: new TreeItem(pi, SWT.NONE);
		final Text editor = new Text(tree, SWT.BORDER);
		editor.addKeyListener(new KeyAdapter() {
			@Override
			public void keyPressed(KeyEvent e) {
				if (e.character == SWT.CR) {
					try {
						Template f = newTemplate(parent, editor.getText());
						if (f != null) {
							tree.setSelection(createFileItem(f, parent));
							editor.dispose();
							item.dispose();
						} else {
							editor.setSelection(0);
						}
					} catch (Exception e1) {
						e1.printStackTrace();
					}
				} else if (e.character == SWT.ESC) {
					editor.dispose();
					item.dispose();
				}
			}
		});
		ed.setEditor(editor, item);
		editor.setText("新模版");
		editor.setFocus();
		editor.setSelection(0, editor.getText().length());
		tree.setSelection(item);
	}

	protected void doSubmit() {

	}

	public void buildTree() {
		treeItems.clear();
	}

	protected abstract void doPreview();

	protected abstract void doOpenResource();

	protected abstract Folder newFolder(TreeItem parent, String name);

	protected abstract Template newTemplate(TreeItem parent, String name);

	protected abstract void doDelete();

	protected abstract boolean redrawItem(GC gc, TreeItem i);

	/**
	 * Create the actions.
	 */
	private void createActions() {
		// Create the actions
		actPreview = new Action("预览") {
			public void run() {
				doPreview();
			};
		};
		actDel = new Action("删除") {
			public void run() {
				doDelete();
			};
		};
		actNew = new Action("新建模版") {
			public void run() {
				doCreateTemplate();
			};
		};
		actNewFolder = new Action("新建目录") {
			public void run() {
				doCreateFolder();
			};
		};
		actSubmit = new Action("提交") {
			public void run() {
				doSubmit();
			};
		};
	}

	/**
	 * Initialize the toolbar.
	 */
	private void initializeToolBar() {
		IToolBarManager toolbarManager = getViewSite().getActionBars()
				.getToolBarManager();
	}

	/**
	 * Initialize the menu.
	 */
	private void initializeMenu() {
		final MenuManager menuManager = new MenuManager();
		menuManager.add(actPreview);
		menuManager.add(new Separator());
		menuManager.add(actNew);
		menuManager.add(actNewFolder);
		menuManager.add(new Separator());
		menuManager.add(actDel);
		menuManager.add(new Separator());
		menuManager.add(actSubmit);
		Menu menu = menuManager.createContextMenu(tree);
		tree.setMenu(menu);
		menu.addMenuListener(new MenuAdapter() {
			@Override
			public void menuShown(MenuEvent e) {
				doShowMenu();
			}
		});
	}

	protected void doShowMenu() {
		Object sd = getSelectedData();
		if (sd instanceof Folder) {
			actPreview.setEnabled(false);
			actDel.setEnabled(true);
		} else if (sd instanceof Template) {
			actPreview.setEnabled(true);
			actDel.setEnabled(true);
		} else {
			actPreview.setEnabled(false);
			actDel.setEnabled(false);
		}
	}

	@Override
	public void setFocus() {
		// Set the focus
	}

	protected TreeItem createFolderItem(Folder f, TreeItem parent) {
		TreeItem item = parent == null ? new TreeItem(tree, SWT.NONE)
				: new TreeItem(parent, SWT.NONE);
		item.setText(f.getName());
		item.setData(f);
		item.setImage(imageFolder);
		treeItems.put(f, item);
		return item;
	}

	protected TreeItem createFileItem(Template t, TreeItem parent) {
		TreeItem item = parent == null ? new TreeItem(tree, SWT.NONE)
				: new TreeItem(parent, SWT.NONE);
		item.setText(t.getName());
		item.setData(t);
		item.setImage(imageFile);
		treeItems.put(t, item);
		return item;
	}

	protected TreeItem findTreeItem(Object obj) {
		return treeItems.get(obj);
	}
}
